package cn.demoncat.util.lang;

import cn.demoncat.util.exception.ParamRuntimeException;
import cn.demoncat.util.lang.constant.StringConstant;
import cn.demoncat.util.lang.entity.ListStr;
import cn.demoncat.util.lang.entity.ReferComparator;
import cn.demoncat.util.lang.fn.BatchHandler;
import cn.demoncat.util.lang.fn.Consumer2;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;

import java.math.BigDecimal;
import java.util.*;
import java.util.Map.Entry;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;

/**
 * 集合工具
 *
 * 常见问题：因为线程安全问题，执行 list.parallelStream().forEach(o -> list2.add(o)) 后，list.size > list2.size 并且 list2.contains(null) == true，这种情况须使用list.stream().forEach()
 * 
 * @author 延晓磊
 *
 * @since 2016年6月10日
 */
public class CollectionUtil {

	/**
	 * 判断是否为集合
	 * 
	 * @param o
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年10月10日
	 */
	public static boolean isCollection(Object o) {
		return o instanceof Collection;
	}

	/**
	 * 判断是否为集合
	 * 
	 * @param clazz
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年10月10日
	 */
	public static boolean isCollection(Class<?> clazz) {
		return ReflectClassUtil.isSupper(Collection.class, clazz);
	}

	/**
	 * 判断集合的元素是否都为空
	 * 
	 * @param collection
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2017年12月30日
	 */
	public static <T> boolean isAllNull(Collection<T> collection) {
		for (T el : collection) {
			if (el != null) {
				return true;
			}
		}
		return false;
	}

	/**
	 * 判断Collection是否非空
	 * 
	 * @param c
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2016年6月10日
	 */
	public static boolean isNotEmpty(Collection<?> c) {
		return CollectionUtils.isNotEmpty(c);
	}

	/**
	 * 判断Map是否非空
	 * 
	 * @param map
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2016年6月10日
	 */
	public static boolean isNotEmpty(Map<?, ?> map) {
		return map != null && !map.isEmpty();
	}

	/**
	 * 判断Collection是否为空
	 * 
	 * @param c
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2016年6月10日
	 */
	public static boolean isEmpty(Collection<?> c) {
		return CollectionUtils.isEmpty(c);
	}

	/**
	 * 判断Map是否为空
	 * 
	 * @param map
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2016年6月10日
	 */
	public static boolean isEmpty(Map<?, ?> map) {
		return !isNotEmpty(map);
	}

	/**
	 * 获取集合的元素类型
	 * 
	 * @param col
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年7月14日
	 */
	public static <E> Class<?> getType(Collection<E> col) {
		// 通过元素获取
		for (E e : col) {
			if (e != null) {
				return e.getClass();
			}
		}
		// 无法反射获取
		return null;
	}

	/**
	 * 是否包含
	 * 
	 * @param col
	 *            集合
	 * @param e
	 *            元素
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年4月5日
	 */
	public static <E> boolean contains(Collection<E> col, E e) {
		if (CollectionUtils.isEmpty(col)) {
			return false;
		}
		return col.contains(e);
	}

	/**
	 * 遍历
	 *
	 * @param list
	 * @param fn	如果list非空则遍历
	 * @param <E>
	 */
	public static <E> void forEach(Collection<E> list, Consumer<E> fn){
		if (CollectionUtils.isNotEmpty(list)) {
			for (E e : list) {
				fn.accept(e);
			}
		}
	}

	/**
	 * 遍历
	 *
	 * @param list
	 * @param fn	如果list非空则遍历
	 * @param <E>
	 */
	public static <E> void forEach(List<E> list, Consumer2<E,Integer> fn){
		if (CollectionUtils.isNotEmpty(list)) {
			E e;
			for (int i = 0; i < list.size(); i++) {
				e = list.get(i);
				fn.accept(e, i);
			}
		}
	}

	/**
	 * 批量删除素
	 * 
	 * @param list
	 *            集合
	 * @param condition
	 *            删除条件
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年7月28日
	 */
	public static <C extends Collection<E>, E> C remove(C list, Predicate<E> condition) {
		if (list == null || list.isEmpty()) {
			return list;
		}
		// 遍历，条件删除
		list.removeIf(condition);
		return list;
	}

	/**
	 * 添加
	 * 
	 * @param list
	 *            源集合，如果为空则新建
	 * @param els
	 *            元素，如果为空则忽略
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年10月12日
	 */
	@SafeVarargs
	public static <E> List<E> add(List<E> list, E... els) {
		if (list == null) {
			list = new ArrayList<>();
		}
		if (els != null) {
			for (E e : els) {
				if (e != null) {
					list.add(e);
				}
			}
		}
		return list;
	}

	/**
	 * 添加
	 *
	 * @param list		当前列表
	 * @param newList	新增元素
	 * @param <E>
	 * @return	当前列表
	 *
	 * @author 延晓磊
	 * @since 2023年01月31日
	 */
	public static <E>List<E> add(List<E> list, List<E> newList){
		list.addAll(newList);
		return list;
	}

	/**
	 * 去重添加
	 *
	 * @param list		当前列表
	 * @param newList	新增元素
	 * @param <E>
	 * @return	当前列表
	 *
	 * @author 延晓磊
	 * @since 2023年01月31日
	 */
	public static <E>List<E> distinctAdd(List<E> list, List<E> newList){
		for (E e : newList) {
			if (!list.contains(e)) {
				list.add(e);
			}
		}
		return list;
	}

	/**
	 * 添加到头部
	 *
	 * @param list
	 *            源集合，如果为空则新建
	 * @param e
	 *            元素，如果为空则忽略
	 *
	 * @author 延晓磊
	 *
	 * @since 2019年10月12日
	 */
	public static <E> List<E> insert(List<E> list, E e) {
		if (list == null) {
			list = new ArrayList<>();
		}
		if (e != null) {
			list.add(0, e);
		}
		return list;
	}

	/**
	 * 合并
	 *
	 * @param collection
	 * @param <T>
	 * @return
	 *
	 * @author 延晓磊
	 * @since 2023年09月18日
	 */
	public static <T>List<T> merge(Collection<List<T>> collection){
		List<T> list = new ArrayList<>();
		if (CollectionUtils.isNotEmpty(collection)) {
			collection.forEach(list::addAll);
		}
		return list;
	}

	/**
	 * 添加
	 * 
	 * @param list
	 *            源集合，如果为空则新建
	 * @param els
	 *            元素，如果为空则忽略
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年10月12日
	 */
	@SafeVarargs
	public static <E> Set<E> add(Set<E> list, E... els) {
		if (list == null) {
			list = new HashSet<>();
		}
		if (els != null) {
			for (E e : els) {
				if (e != null) {
					list.add(e);
				}
			}
		}
		return list;
	}

	/**
	 * 添加非空元素集: 如果Collection为空返回false；如果elements为空返回false；如果都不为空则添加并返回true
	 * 
	 * @param c
	 * @param es
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2016年6月10日
	 */
	public static <E> boolean addNotNullElements(Collection<E> c, Collection<E> es) {
		if (c == null) {
			return false;
		}
		if (!CollectionUtils.isEmpty(es)) {
			return false;
		}
		c.addAll(es);
		return true;
	}

	/**
	 * 查找元素
	 *
	 * @param list		列表
	 * @param predicate	条件
	 * @return 首个满足条件的元素
	 *
	 * @author 延晓磊
	 *
	 * @since 2016年6月10日
	 */
	public static <E> E get(Collection<E> list, Predicate<? super E> predicate) {
		return first(list, predicate);
	}

	/**
	 * 获取List的元素
	 * 
	 * @param list
	 * @param index
	 *            0首个，-1末个
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2016年6月10日
	 */
	public static <E> E get(List<E> list, int index) {
		// 非空
		if (list == null || list.isEmpty() || index > list.size() - 1) {
			return null;
		}
		// 倒数
		if (index < 0) {
			index = list.size() + index;
			if (index < 0) {
				return null;
			}
		}
		return list.get(index);
	}

	/**
	 * 随意获取1条数据
	 *
	 * @param list
	 * @param <T>
	 * @return 遍历的第一条
	 *
	 * @author 延晓磊
	 * @since 2022年07月29日
	 */
	public static <T>T any(Collection<T> list){
		if (CollectionUtils.isEmpty(list)) {
			return null;
		}
		for (T t : list) {
		    return t;
		}
		return null;
	}

	/**
	 * 获取List的首个元素
	 *
	 * @param list
	 * @return
	 *
	 * @author 延晓磊
	 *
	 * @since 2016年6月10日
	 */
	public static <E> E first(List<E> list) {
		return list == null || list.isEmpty() ? null : list.get(0);
	}

	/**
	 * 获取List的首个元素
	 *
	 * @param list
	 * @param predicate	条件
	 * @return
	 *
	 * @author 延晓磊
	 *
	 * @since 2016年6月10日
	 */
	public static <E> E first(Collection<E> list, Predicate<? super E> predicate) {
		if (CollectionUtils.isEmpty(list) || predicate == null) {
			return null;
		}
		for (E e : list) {
			if (predicate.test(e)) {
				return e;
			}
		}
		return null;
	}

	/**
	 * 获取List的末个元素
	 *
	 * @param list
	 * @return
	 *
	 * @author 延晓磊
	 *
	 * @since 2016年6月10日
	 */
	public static <E> E last(List<E> list) {
		return list == null || list.isEmpty() ? null : list.get(list.size() - 1);
	}

	/**
	 * 获取List的末个元素
	 *
	 * @param list
	 * @param predicate	条件
	 * @return
	 *
	 * @author 延晓磊
	 *
	 * @since 2016年6月10日
	 */
	public static <E> E last(List<E> list, Predicate<? super E> predicate) {
		if (CollectionUtils.isEmpty(list) || predicate == null) {
			return null;
		}
		for (int i = list.size()-1; i >= 0; i--) {
			if (predicate.test(list.get(i))) {
				return list.get(i);
			}
		}
		return null;
	}

	/**
	 * 排序
	 * 
	 * @param list
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年7月29日
	 */
	public static <E extends Comparable<E>> List<E> sort(List<E> list) {
		Collections.sort(list);
		return list;
	}

	/**
	 * 排序
	 * 
	 * @param list
	 * @param comparator
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年7月29日
	 */
	public static <E> List<E> sort(List<E> list, Comparator<E> comparator) {
		list.sort(comparator);
		return list;
	}

	/**
	 * 排序
	 *
	 * @param list
	 * @param referList		参照列表（元素为list元素的某个字段，即参照字段，如 id）
	 * @param referGetter	获取参照元素的方法（获取list元素的参照字段，如 o.getId）
	 *
	 * @return
	 *
	 * @author 延晓磊
	 *
	 * @since 2020年7月29日
	 */
	public static <E,R> List<E> sort(List<E> list, List<R> referList, Function<E,R> referGetter) {
		return sort(list, ReferComparator.build(referList, referGetter));
	}

	/**
	 * 逆序
	 *
	 * @param list
	 * @return
	 *
	 * @author 延晓磊
	 *
	 * @since 2020年7月29日
	 */
	public static <E> List<E> reverse(List<E> list) {
		Collections.reverse(list);
		return list;
	}

	/**
	 * 列表去重
	 *
	 * @param list
	 * @param resolver	解析器（获取元素的唯一比较值）
	 * @param <E>
	 * @param <R>
	 * @return
	 *
	 * @author 延晓磊
	 * @since 2022年12月29日
	 */
	public static <E,R>List<E> distinct(List<E> list, Function<E,R> resolver){
		Set<R> rs = new HashSet<>();
		return list.stream().filter(e -> rs.add(resolver.apply(e))).collect(Collectors.toList());
	}

	/**
	 * 创建List
	 * 
	 * @param ts
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年8月27日
	 */
	@SafeVarargs
	public static <T> List<T> toList(T... ts) {
		return arrayToList(ts);
	}

	/**
	 * 转换为List
	 *
	 * @param list
	 * @param fn	通过实例获取字段
	 * @param <T>	实例
	 * @param <F>	字段
	 * @return 字段列表
	 *
	 * @author 延晓磊
	 * @since 2023年09月15日
	 */
	public static <T,F> List<F> toList(Collection<T> list, Function<T,F> fn){
		return list.stream().map(fn).collect(Collectors.toList());
	}

	/**
	 * 创建List
	 * 
	 * @param ts
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年8月27日
	 */
	public static <T> List<T> asList(Iterator<T> ts) {
		List<T> list = new ArrayList<>();
		while (ts.hasNext()) {
			list.add(ts.next());
		}
		return list;
	}
	
	/**
	 * 创建List
	 * 
	 * @param ts
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年8月27日
	 */
	public static <T> List<T> asList(Iterable<T> ts) {
		List<T> list = new ArrayList<>();
		for (T t : ts) {
			list.add(t);
		}
		return list;
	}

	/**
	 * 创建Set
	 * 
	 * @param ts
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年8月27日
	 */
	@SafeVarargs
	public static <T> Set<T> toSet(T... ts) {
		return arrayToSet(ts);
	}

	/**
	 * 转换为Set
	 *
	 * @param list
	 * @param fn	通过实例获取字段
	 * @param <T>	实例
	 * @param <F>	字段
	 * @return 字段列表
	 *
	 * @author 延晓磊
	 * @since 2023年09月15日
	 */
	public static <T,F> Set<F> toSet(Collection<T> list, Function<T,F> fn){
		return list.stream().map(fn).collect(Collectors.toSet());
	}

	/**
	 * 
	 * 功能描述：切割字符串为String List
	 *
	 * @param ids
	 * @return null > null, '' > [], '1,2' > [1,2]
	 * 
	 * @author 延晓磊
	 */
	public static List<String> toStrList(String ids) {
		String[] split = StringUtil.splitStrict(ids);
		if (split != null) {
			List<String> ls = new ArrayList<>(split.length);
			Collections.addAll(ls, split);
			return ls;
		}
		return null;
	}

	/**
	 * 将List转换为字符串List，空元素转""
	 *
	 * @param list
	 * @return List(String)
	 * 
	 * @author 延晓磊
	 */
	public static <T> List<String> toStrList(Collection<T> list) {
		return list.stream().map(StringUtil::toEmptyString).collect(Collectors.toList());
	}

	/**
	 * 
	 * 功能描述：切割字符串为String Set
	 *
	 * @param ids
	 * @return null > null, '' > [], '1,2' > [1,2]
	 * 
	 * @author 延晓磊
	 */
	public static Set<String> toStrSet(String ids) {
		String[] split = StringUtil.splitStrict(ids);
		if (split != null) {
			Set<String> ls = new HashSet<>(split.length);
			Collections.addAll(ls, split);
			return ls;
		}
		return null;
	}

	/**
	 * 将List转换为字符串Set，去除空元素
	 *
	 * @param list
	 * @return List(String)
	 * 
	 * @author 延晓磊
	 */
	public static <T> Set<String> toStrSet(Collection<T> list) {
		Set<String> collect = list.stream().map(StringUtil::toEmptyString).collect(Collectors.toSet());
		// 去除“”
		collect.remove(StringConstant.EMPTY);
		return collect;
	}

	/**
	 * 功能描述：切割字符串为Integer数组
	 *
	 * @param ids
	 * @return
	 * 
	 * @author 延晓磊
	 */
	public static List<Integer> toIntList(String ids) {
		String[] split = StringUtil.splitStrict(ids);
		if (split != null) {
			List<Integer> ls = new ArrayList<>(split.length);
			for (String s : split) {
				ls.add(IntegerUtil.valueOf(s));
			}
			return ls;
		}
		return null;
	}

	/**
	 * 
	 * 功能描述：切割字符串为Integer Set
	 *
	 * @param ids
	 * @return
	 * 
	 * @author 延晓磊
	 */
	public static Set<Integer> toIntSet(String ids) {
		String[] split = StringUtil.splitStrict(ids);
		if (split != null) {
			Set<Integer> ls = new HashSet<>(split.length);
			for (String s : split) {
				ls.add(IntegerUtil.valueOf(s));
			}
			return ls;
		}
		return null;
	}

	/**
	 * 功能描述：切割字符串为Long列表
	 *
	 * @param ids
	 * @return "" = [],"10,20" = [10,20]
	 * 
	 * @author 延晓磊
	 */
	public static List<Long> toLongList(String ids) {
		String[] split = StringUtil.splitStrict(ids);
		if (split != null) {
			List<Long> ls = new ArrayList<>(split.length);
			for (String s : split) {
				ls.add(LongUtil.valueOf(s));
			}
			return ls;
		}
		return null;
	}

	/**
	 * 功能描述：切割字符串为Long Set
	 *
	 * @param ids
	 * @return
	 * 
	 * @author 延晓磊
	 */
	public static Set<Long> toLongSet(String ids) {
		String[] split = StringUtil.splitStrict(ids);
		if (split != null) {
			Set<Long> ls = new HashSet<>(split.length);
			for (String s : split) {
				ls.add(LongUtil.valueOf(s));
			}
			return ls;
		}
		return null;
	}

	/**
	 * 数组转换为List
	 * 
	 * @param es
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2016年6月10日
	 */
	public static <E> List<E> arrayToList(E[] es) {
		if (es == null) {
			return null;
		}
		List<E> list = new ArrayList<>(es.length);
		Collections.addAll(list, es);
		return list;
	}

	/**
	 * 数组转换为Set
	 * 
	 * @param es
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2016年6月10日
	 */
	public static <E> Set<E> arrayToSet(E[] es) {
		if (es == null) {
			return null;
		}
		Set<E> list = new HashSet<>(es.length);
		Collections.addAll(list, es);
		return list;
	}

	/**
	 * 集合转数组
	 * 
	 * @param collection
	 * @param arr
	 *            结果数组：如果为null，将通过collection.get(0)获取类型并创建；如果length小于collection.size将新建数组，否则直接调用System.arraycopy
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2017年10月31日
	 */
	public static <T> T[] toArray(Collection<T> collection, T[] arr) {
		// 集合为空时返回null
		if (collection == null || collection.isEmpty()) {
			return null;
		}
		// 创建数组：通过集合元素获取类型
		if (arr == null) {
			arr = ArrayUtil.instance(getType(collection), 0);
		}
		// 转换数组：System.arraycopy
		return collection.toArray(arr);
	}

	/**
	 * 集合转数组
	 * 
	 * @param collection
	 * 
	 * @return 数组：集合为空、元素都为null时返回null
	 * 
	 * @author 延晓磊
	 *
	 * @since 2017年10月31日
	 */
	public static <T> T[] toArray(Collection<T> collection) {
		return toArray(collection, null);
	}

	/**
	 * 集合转数组
	 * 
	 * 注：Java - Collection的toArray是经过复杂的反射后进行遍历，不如直接遍历效率高
	 * 
	 * @param collection
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2017年10月31日
	 */
	public static <E> String[] toStrArray(Collection<E> collection) {
		if (collection == null) {
			return null;
		}
		String[] arr = new String[collection.size()];
		int i = 0;
		for (E e : collection) {
			arr[i] = StringUtil.toString(e);
			i++;
		}
		return arr;
	}

	/**
	 * 集合转数组
	 * 
	 * @param collection
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2017年10月31日
	 */
	public static Long[] toLongArray(Collection<Long> collection) {
		if (collection == null) {
			return null;
		}
		Long[] arr = new Long[collection.size()];
		int i = 0;
		for (Long e : collection) {
			arr[i] = e;
			i++;
		}
		return arr;
	}

	/**
	 * 集合转数组
	 * 
	 * @param collection
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2017年10月31日
	 */
	public static Integer[] toIntArray(Collection<Integer> collection) {
		if (collection == null) {
			return null;
		}
		Integer[] arr = new Integer[collection.size()];
		int i = 0;
		for (Integer e : collection) {
			arr[i] = e;
			i++;
		}
		return arr;
	}

	/**
	 * 转换为Map
	 * 
	 * @param collection
	 * @return {k:k}
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年3月6日
	 */
	public static <K> Map<K, K> toMap(Collection<K> collection) {
		HashMap<K, K> map = new HashMap<>();
		if (CollectionUtils.isNotEmpty(collection)) {
			for (K k : collection) {
				map.put(k, k);
			}
		}
		return map;
	}

	/**
	 * 转换为Map
	 * 
	 * @param collection
	 * @param v 默认值
	 *
	 * @return {k:v}
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年3月6日
	 */
	public static <K, V> Map<K, V> toMap(Collection<K> collection, V v) {
		HashMap<K, V> map = new HashMap<>();
		if (CollectionUtils.isNotEmpty(collection)) {
			for (K k : collection) {
				map.put(k, v);
			}
		}
		return map;
	}

	/**
	 * 转换为Map
	 *
	 * @param collection
	 * @param k
	 * @return {k:o}
	 *
	 * @author 延晓磊
	 *
	 * @since 2020-9-18
	 */
	public static <K,O> Map<K,O> toMap(Collection<O> collection, Function<O,K> k){
		return toMap(collection, k, o -> o);
	}

	/**
	 * 转换为Map
	 *
	 * @param collection
	 * @param k
	 * @return {'k':o}
	 *
	 * @author 延晓磊
	 *
	 * @since 2020-9-18
	 */
	public static <K,O> Map<String,O> toStrMap(Collection<O> collection, Function<O,K> k){
		return toStrMap(collection, k, o -> o);
	}

	/**
	 * 转换为Map
	 * 
	 * @param collection
	 * @param k
	 * @param v
	 * @return {k:v}
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020-9-18
	 */
	public static <O,K,V> Map<K,V> toMap(Collection<O> collection, Function<O,K> k, Function<O,V> v){
		Map<K,V> map = new HashMap<>();
		if (CollectionUtils.isNotEmpty(collection)) {
			collection.forEach(e -> map.put(k.apply(e), v.apply(e)));
		}
		return map;
	}

	/**
	 * 转换为Map
	 *
	 * @param collection
	 * @param k
	 * @param v
	 * @return {'k':v}
	 *
	 * @author 延晓磊
	 *
	 * @since 2020-9-18
	 */
	public static <O,K,V> Map<String,V> toStrMap(Collection<O> collection, Function<O,K> k, Function<O,V> v){
		return toMap(collection, o -> StringUtil.toString(k.apply(o)), v);
	}

	/**
	 * 转换为Map
	 *
	 * @param collection
	 * @param k
	 * @return {k:[o]}
	 *
	 * @author 延晓磊
	 *
	 * @since 2020-9-18
	 */
	public static <K,O> Map<K,List<O>> toMapList(Collection<O> collection, Function<O,K> k){
		Map<K,List<O>> map = new HashMap<>();
		if (CollectionUtils.isNotEmpty(collection)) {
			for (O o : collection) {
				map.computeIfAbsent(k.apply(o), key -> new ArrayList<>()).add(o);
			}
		}
		return map;
	}

	/**
	 * 转换为Map
	 *
	 * @param collection
	 * @param k
	 * @return {k:[o]}
	 *
	 * @author 延晓磊
	 *
	 * @since 2020-9-18
	 */
	public static <K,O> Map<K,Set<O>> toMapSet(Collection<O> collection, Function<O,K> k){
		Map<K,Set<O>> map = new HashMap<>();
		if (CollectionUtils.isNotEmpty(collection)) {
			for (O o : collection) {
				map.computeIfAbsent(k.apply(o), key -> new HashSet<>()).add(o);
			}
		}
		return map;
	}

	/**
	 * 转换为Map
	 *
	 * @param collection
	 * @param k
	 * @return {k:[v]}
	 *
	 * @author 延晓磊
	 *
	 * @since 2020-9-18
	 */
	public static <O,K,V> Map<K,List<V>> toMapList(Collection<O> collection, Function<O,K> k, Function<O,V> v){
		Map<K,List<V>> map = new HashMap<>();
		if (CollectionUtils.isNotEmpty(collection)) {
			for (O o : collection) {
				map.computeIfAbsent(k.apply(o), key -> new ArrayList<>()).add(v.apply(o));
			}
		}
		return map;
	}

	/**
	 * 转换为Map
	 *
	 * @param collection
	 * @param k
	 * @return {k:[v]}
	 *
	 * @author 延晓磊
	 *
	 * @since 2020-9-18
	 */
	public static <O,K,V> Map<K,Set<V>> toMapSet(Collection<O> collection, Function<O,K> k, Function<O,V> v){
		Map<K,Set<V>> map = new HashMap<>();
		if (CollectionUtils.isNotEmpty(collection)) {
			for (O o : collection) {
				map.computeIfAbsent(k.apply(o), key -> new HashSet<>()).add(v.apply(o));
			}
		}
		return map;
	}

	/**
	 * 转换为LinkedMap
	 *
	 * @param collection
	 * @param k
	 * @return {k:o}
	 *
	 * @author 延晓磊
	 *
	 * @since 2020-9-18
	 */
	public static <O,K> Map<K,O> toLinkedMap(Collection<O> collection, Function<O,K> k){
		return toLinkedMap(collection, k, o -> o);
	}

	/**
	 * 转换为LinkedMap
	 *
	 * @param collection
	 * @param k
	 * @return {'k':o}
	 *
	 * @author 延晓磊
	 *
	 * @since 2020-9-18
	 */
	public static <O,K> Map<String,O> toLinkedStrMap(Collection<O> collection, Function<O,K> k){
		return toLinkedStrMap(collection, k, o -> o);
	}

	/**
	 * 转换为LinkedMap
	 *
	 * @param collection
	 * @param k
	 * @param v
	 * @return {k:v}
	 *
	 * @author 延晓磊
	 *
	 * @since 2020-9-18
	 */
	public static <O,K,V> Map<K,V> toLinkedMap(Collection<O> collection, Function<O,K> k, Function<O,V> v){
		Map<K,V> map = new LinkedHashMap<>();
		if (CollectionUtils.isNotEmpty(collection)) {
			collection.forEach(e -> map.put(k.apply(e), v.apply(e)));
		}
		return map;
	}

	/**
	 * 转换为LinkedMap
	 *
	 * @param collection
	 * @param k
	 * @param v
	 * @return {'k':v}
	 *
	 * @author 延晓磊
	 *
	 * @since 2020-9-18
	 */
	public static <O,K,V> Map<String,V> toLinkedStrMap(Collection<O> collection, Function<O,K> k, Function<O,V> v){
		return toLinkedMap(collection, o -> StringUtil.toString(k.apply(o)), v);
	}

	/**
	 * 去除空元素
	 * 
	 * @param collection
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年8月16日
	 */
	public static <T> List<T> trim(Collection<T> collection) {
		if (collection == null) {
			return null;
		}
		if (collection.isEmpty()) {
			return new ArrayList<>(0);
		}
		List<T> list = new ArrayList<>(collection.size());
		for (T el : collection) {
			if (el != null) {
				list.add(el);
			}
		}
		return list;
	}

	/**
	 * 去除空元素
	 * 
	 * @param collection
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年8月16日
	 */
	public static List<String> trimStr(Collection<String> collection) {
		if (collection == null) {
			return null;
		}
		if (collection.isEmpty()) {
			return ListStr.EMPTY;
		}
		List<String> list = new ArrayList<>(collection.size());
		for (String str : collection) {
			if (StringUtils.isNotBlank(str)) {
				list.add(str);
			}
		}
		return list;
	}

	/**
	 * 去除空元素
	 * 
	 * @param collection
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年8月16日
	 */
	public static <T> Set<T> trimToSet(Collection<T> collection) {
		if (collection == null) {
			return null;
		}
		if (collection.isEmpty()) {
			return new HashSet<>(0);
		}
		Set<T> list = new HashSet<>(collection.size());
		for (T el : collection) {
			if (el != null) {
				list.add(el);
			}
		}
		return list;
	}

	/**
	 * 去除空元素
	 * 
	 * @param collection
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年8月16日
	 */
	public static Set<String> trimStrToSet(Collection<String> collection) {
		if (collection == null) {
			return null;
		}
		if (collection.isEmpty()) {
			return new HashSet<>(0);
		}
		Set<String> list = new HashSet<>(collection.size());
		for (String str : collection) {
			if (StringUtils.isNotBlank(str)) {
				list.add(str);
			}
		}
		return list;
	}

	/**
	 * 并集：t1 + t2
	 * 
	 * @param t1
	 * @param t2
	 * @return 并集
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年8月27日
	 */
	public static <T> Set<T> union(Set<T> t1, Set<T> t2) {
		Set<T> list = new HashSet<>();
		if (CollectionUtils.isNotEmpty(t1)) {
			list.addAll(t1);
		}
		if (CollectionUtils.isNotEmpty(t2)) {
			list.addAll(t2);
		}
		return list;
	}

	/**
	 * 并集：t1 + t2
	 *
	 * @param t1
	 * @param t2
	 * @return 并集 t1 / t2（t1为空）
	 *
	 * @author 延晓磊
	 *
	 * @since 2019年8月27日
	 */
	public static <T> Set<T> toUnion(Set<T> t1, Set<T> t2) {
		if (CollectionUtils.isEmpty(t1)) {
			return t2;
		}
		if (CollectionUtils.isEmpty(t2)) {
			return t1;
		}
		t1.addAll(t2);
		return t1;
	}

	/**
	 * 并集：t1 + t2
	 * 
	 * @param t1
	 * @param t2
	 * @return 并集
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年8月27日
	 */
	public static <T> List<T> union(List<T> t1, List<T> t2) {
		List<T> list = new ArrayList<>();
		if (CollectionUtils.isNotEmpty(t1)) {
			list.addAll(t1);
		}
		if (CollectionUtils.isNotEmpty(t2)) {
			list.addAll(t2);
		}
		return list;
	}

	/**
	 * 并集：t1 + t2
	 *
	 * @param t1
	 * @param t2
	 * @return 并集 t1 / t2（t1为空）
	 *
	 * @author 延晓磊
	 *
	 * @since 2019年8月27日
	 */
	public static <T> List<T> toUnion(List<T> t1, List<T> t2) {
		if (CollectionUtils.isEmpty(t1)) {
			return t2;
		}
		if (CollectionUtils.isEmpty(t2)) {
			return t1;
		}
		t1.addAll(t2);
		return t1;
	}

	/**
	 * 并集：t1 + t2，重复时以t2为准
	 * 
	 * @param t1
	 * @param t2
	 * @return 并集
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年8月27日
	 */
	public static <K, V> Map<K, V> union(Map<K, V> t1, Map<K, V> t2) {
		Map<K,V> map = new HashMap<>();
		if (MapUtils.isNotEmpty(t1)) {
			map.putAll(t1);
		}
		if (MapUtils.isNotEmpty(t2)) {
			map.putAll(t2);
		}
		return map;
	}

	/**
	 * 并集：t1 + t2，重复时以t2为准
	 *
	 * @param t1
	 * @param t2
	 * @return 并集 t1 / t2（t1为空）
	 *
	 * @author 延晓磊
	 *
	 * @since 2019年8月27日
	 */
	public static <K, V> Map<K, V> toUnion(Map<K, V> t1, Map<K, V> t2) {
		if (MapUtils.isEmpty(t1)) {
			return t2;
		}
		if (MapUtils.isEmpty(t2)) {
			return t1;
		}
		t1.putAll(t2);
		return t1;
	}

	/**
	 * 交集：t1 - (t1 - t2)
	 * 
	 * @param t1
	 * @param t2
	 * @return 交集
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年8月27日
	 */
	public static <T> Set<T> intersection(Set<T> t1, Set<T> t2) {
		Set<T> list = new HashSet<>();
		if (CollectionUtils.isEmpty(t1) || CollectionUtils.isEmpty(t2)) {
			return list;
		}
		list.addAll(t1);
		list.retainAll(t2);
		return list;
	}

	/**
	 * 交集：t1 - (t1 - t2)
	 *
	 * @param t1
	 * @param t2
	 * @return 交集 t1
	 *
	 * @author 延晓磊
	 *
	 * @since 2019年8月27日
	 */
	public static <T> Set<T> toIntersection(Set<T> t1, Set<T> t2) {
		if (CollectionUtils.isEmpty(t1) || CollectionUtils.isEmpty(t2)) {
			return new HashSet<>();
		}
		t1.retainAll(t2);
		return t1;
	}

	/**
	 * 交集：t1 - (t1 - t2)
	 * 
	 * @param t1
	 * @param t2
	 * @return 交集
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年8月27日
	 */
	public static <T> List<T> intersection(List<T> t1, List<T> t2) {
		List<T> list = new ArrayList<>();
		if (CollectionUtils.isEmpty(t1) || CollectionUtils.isEmpty(t2)) {
			return list;
		}
		list.addAll(t1);
		list.retainAll(t2);
		return list;
	}

	/**
	 * 交集：t1 - (t1 - t2)
	 *
	 * @param t1
	 * @param t2
	 * @return 交集 t1
	 *
	 * @author 延晓磊
	 *
	 * @since 2019年8月27日
	 */
	public static <T> List<T> toIntersection(List<T> t1, List<T> t2) {
		if (CollectionUtils.isEmpty(t1) || CollectionUtils.isEmpty(t2)) {
			return new ArrayList<>();
		}
		t1.retainAll(t2);
		return t1;
	}

	/**
	 * 交集：t1 - (t1 - t2)，重复时以t1为准
	 * 
	 * @param t1
	 * @param t2
	 * @return 交集
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年8月27日
	 */
	public static <K, V> Map<K, V> intersection(Map<K, V> t1, Map<K, V> t2) {
		Map<K,V> map = new HashMap<>();
		if (MapUtils.isEmpty(t1) || MapUtils.isEmpty(t2)) {
			return map;
		}
		map.putAll(t1);
		map.keySet().retainAll(t2.keySet());
		return map;
	}

	/**
	 * 交集：t1 - (t1 - t2)，重复时以t1为准
	 *
	 * @param t1
	 * @param t2
	 * @return 交集 t1
	 *
	 * @author 延晓磊
	 *
	 * @since 2019年8月27日
	 */
	public static <K, V> Map<K, V> toIntersection(Map<K, V> t1, Map<K, V> t2) {
		if (MapUtils.isEmpty(t1) || MapUtils.isEmpty(t2)) {
			return new HashMap<>();
		}
		t1.keySet().retainAll(t2.keySet());
		return t1;
	}

	/**
	 * 差集：t1 - t2
	 * 
	 * @param t1
	 * @param t2
	 * @return 差集
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年8月27日
	 */
	public static <T> Set<T> subtract(Set<T> t1, Set<T> t2) {
		Set<T> list = new HashSet<>();
		if (CollectionUtils.isEmpty(t1)) {
			return list;
		}
		list.addAll(t1);
		if (CollectionUtils.isNotEmpty(t2)) {
			list.removeAll(t2);
		}
		return list;
	}

	/**
	 * 差集：t1 - t2
	 *
	 * @param t1
	 * @param t2
	 * @return 差集 t1
	 *
	 * @author 延晓磊
	 *
	 * @since 2019年8月27日
	 */
	public static <T> Set<T> toSubtract(Set<T> t1, Set<T> t2) {
		if (CollectionUtils.isEmpty(t1)) {
			return t1;
		}
		if (CollectionUtils.isNotEmpty(t2)) {
			t1.removeAll(t2);
		}
		return t1;
	}

	/**
	 * 差集：t1 - t2
	 * 
	 * @param t1
	 * @param t2
	 * @return 差集
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年8月27日
	 */
	public static <T> List<T> subtract(List<T> t1, List<T> t2) {
		List<T> list = new ArrayList<>();
		if (CollectionUtils.isEmpty(t1)) {
			return list;
		}
		list.addAll(t1);
		if (CollectionUtils.isNotEmpty(t2)) {
			list.removeAll(t2);
		}
		return list;
	}

	/**
	 * 差集：t1 - t2
	 *
	 * @param t1
	 * @param t2
	 * @return 差集 t1
	 *
	 * @author 延晓磊
	 *
	 * @since 2019年8月27日
	 */
	public static <T> List<T> toSubtract(List<T> t1, List<T> t2) {
		if (CollectionUtils.isEmpty(t1)) {
			return t1;
		}
		if (CollectionUtils.isNotEmpty(t2)) {
			t1.removeAll(t2);
		}
		return t1;
	}

	/**
	 * 差集：t1 - t2
	 * 
	 * @param t1
	 * @param t2
	 * @return 差集
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年8月27日
	 */
	public static <K, V> Map<K, V> subtract(Map<K, V> t1, Map<K, V> t2) {
		Map<K,V> map = new HashMap<>();
		if (MapUtils.isEmpty(t1)) {
			return map;
		}
		map.putAll(t1);
		if (MapUtils.isNotEmpty(t2)) {
			map.keySet().removeAll(t2.keySet());
		}
		return map;
	}

	/**
	 * 差集：t1 - t2
	 *
	 * @param t1
	 * @param t2
	 * @return 差集 t1
	 *
	 * @author 延晓磊
	 *
	 * @since 2019年8月27日
	 */
	public static <K, V> Map<K, V> toSubtract(Map<K, V> t1, Map<K, V> t2) {
		if (MapUtils.isEmpty(t1)) {
			return t1;
		}
		if (MapUtils.isNotEmpty(t2)) {
			t1.keySet().removeAll(t2.keySet());
		}
		return t1;
	}

	/**
	 * 分批处理数据
	 * 
	 * @param list
	 *            集合
	 * @param step
	 *            分批数
	 * @param handler
	 *            处理器：停止分批处理时返回非null，继续处理返回null
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年8月22日
	 */
	public static <T, R> R batchs(List<T> list, int step, BatchHandler<T, R> handler) {
		if (CollectionUtils.isEmpty(list)) {
			return null;
		}
		// 不分批
		if (list.size() <= step) {
			return handler.callback(list);
		}
		// 分批
		int times = list.size() % step == 0 ? list.size() / step : list.size() / step + 1;
		R r;
		for (int i = 0; i < times; i++) {
			// 分批处理
			if (i == times - 1) {
				r = handler.callback(list.subList(i * step, list.size()));
			} else {
				r = handler.callback(list.subList(i * step, (i + 1) * step));
			}
			// 返回非null时终止批处理
			if (r != null) {
				return r;
			}
		}
		return null;
	}

	/**
	 * 分批处理数据（无返回）
	 * 
	 * @param list
	 *            集合
	 * @param step
	 *            分批数
	 * @param handler
	 *            处理器
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年8月22日
	 */
	public static <T> void batchs2(List<T> list, int step, Consumer<List<T>> handler) {
		if (CollectionUtils.isEmpty(list)) {
			return;
		}
		// 不分批
		if (list.size() <= step) {
			handler.accept(list);
			return;
		}
		// 分批
		int times = list.size() % step == 0 ? list.size() / step : list.size() / step + 1;
		for (int i = 0; i < times; i++) {
			// 分批处理
			if (i == times - 1) {
				handler.accept(list.subList(i * step, list.size()));
			} else {
				handler.accept(list.subList(i * step, (i + 1) * step));
			}
		}
	}

	/**
	 * 洗牌
	 *
	 * @param list	源list，会被变更
	 * @return 洗牌后的list
	 *
	 * @author 延晓磊
	 *
	 * @since 2019年8月22日
	 */
	public static <T>List<T> shuffle(List<T> list){
		Collections.shuffle(list);
		return list;
	}

	/**
	 * 获取元素的数量
	 *
	 * @param list
	 * @param o
	 * @return
	 *
	 * @author 延晓磊
	 *
	 * @since 2019年8月22日
	 */
	public static <T>int count(List<T> list, T o){
		return Collections.frequency(list, o);
	}

	/**
	 * 随机抽取1个
	 *
	 * @param list	源list
	 * @return 抽取的元素
	 *
	 * @author 延晓磊
	 *
	 * @since 2019年8月22日
	 */
	public static <T>T random(List<T> list){
		if (CollectionUtils.isEmpty(list)) {
			throw new ParamRuntimeException("列表不能为空");
		}
		return list.get(RandomUtil.number(list.size()));
	}

	/**
	 * 随机抽取num个
	 *
	 * @param list	源list，不会被变更
	 * @param num	抽取数量
	 * @return 抽取的新list
	 *
	 * @author 延晓磊
	 *
	 * @since 2019年8月22日
	 */
	public static <T>List<T> random(List<T> list, int num){
		if (num <= 0) {
			throw new ParamRuntimeException("数量必须大于0");
		}
		if (CollectionUtils.isEmpty(list)) {
			throw new ParamRuntimeException("列表不能为空");
		}
		if (list.size() == num) {
			return new ArrayList<>(list);
		}else if (list.size() < num) {
			throw new ParamRuntimeException("列表元素不足");
		}else{
			Set<T> set = new HashSet<>(num);
			List<T> newList = new ArrayList<>();
			Random random = new Random();
			T o;
			while (set.size() < num){
				o = list.get(random.nextInt(list.size()));
				if (set.add(o)) {
					newList.add(o);
				}
			}
			return newList;
		}
	}

	/**
	 * 抽取规则数据
	 * 
	 * 注意：多规则数据交叉冲突可能导致抽取失败，要保证100%需要和九宫格一样做大量的递归探测，服务性能将大打折扣，所以不作完整处理，建议设置数据宽裕些，或者重试
	 * 
	 * @param rules
	 *            规则：需求数量
	 * @param datas
	 *            规则：原始数据
	 * 
	 * @return null数据不足，map抽取结果
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年7月1日
	 */
	public static <R, E> Map<R, List<E>> select(Map<R, Integer> rules, Map<R, List<E>> datas) {
		// 规则数据去重
		for (Entry<R, List<E>> data : datas.entrySet()) {
			data.setValue(new ArrayList<>(new HashSet<>(data.getValue())));
		}
		// 判断是否全部充足
		List<E> curr;
		int ruleCount = 0;
		Set<E> dataCount = new HashSet<>();
		for (Entry<R, Integer> rule : rules.entrySet()) {
			// 规则数据
			curr = datas.get(rule.getKey());
			// 规则数据不足
			if (rule.getValue() > curr.size()) {
				return null;
			}
			// 统计总数
			ruleCount += rule.getValue();
			dataCount.addAll(curr);
		}
		if (ruleCount > dataCount.size()) {
			// 总数量不足
			return null;
		}

		// 抽取数量相等的规则
		Map<R, List<E>> result = new HashMap<>();
		List<R> removes = new ArrayList<>();
		for (Entry<R, Integer> rule : rules.entrySet()) {
			result = selectEquals(result, removes, rule, rules, datas);
			if (result == null) {
				return null;
			}
		}

		// 未抽取完
		if (result.size() < rules.size()) {
			// 清理已抽取的规则
			for (R r : removes) {
				rules.remove(r);
				datas.remove(r);
			}
			// 抽取数量超出的规则（交叉抽取）
			Map<R, List<E>> result2 = selectOverflow(rules, datas);
			if (result2 == null) {
				return null;
			} else {
				result.putAll(result2);
			}
		}
		return result;
	}

	/**
	 * 随机抽取 - 数量相等
	 * 
	 * @param result
	 *            规则：结果数据
	 * @param removes
	 *            删除（抽取过）的规则
	 * @param rule
	 *            当前规则
	 * @param rules
	 *            规则：需求数量
	 * @param datas
	 *            规则：原始数据
	 *
	 * @return null数据不足，map抽取结果
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年7月1日
	 */
	private static <R, E> Map<R, List<E>> selectEquals(Map<R, List<E>> result, List<R> removes, Entry<R, Integer> rule, Map<R, Integer> rules, Map<R, List<E>> datas) {
		// 规则已删除（抽取过）
		if (removes.contains(rule.getKey())) {
			return result;
		}
		// 规则数据
		List<E> curr = datas.get(rule.getKey());
		// 数量不足
		if (rule.getValue() > curr.size()) {
			return null;
		}
		// 数量相等
		if (rule.getValue() == curr.size()) {
			// 保存当前规则数据
			result.put(rule.getKey(), curr);
			// 清除当前规则
			removes.add(rule.getKey());
			// 唯一性清除：同一条数据只能被一种规则抽取
			for (Entry<R, Integer> other : rules.entrySet()) {
				if (!removes.contains(other.getKey())) {
					// 清除未抽取规则下的重复数据
					if (datas.get(other.getKey()).removeAll(curr)) {
						// 递归抽取
						result = selectEquals(result, removes, rule, rules, datas);
					}
				}
			}
		}
		return result;
	}

	/**
	 * 随机抽取 - 数量超出
	 * 
	 * @param rules
	 *            规则：需求数量
	 * @param datas
	 *            规则：原始数据
	 * 
	 * @return null数据不足，map抽取结果
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年7月1日
	 */
	private static <R, E> Map<R, List<E>> selectOverflow(Map<R, Integer> rules, Map<R, List<E>> datas) {
		// 数据计数
		Map<E, Integer> counts = new HashMap<>();
		Integer count;
		for (List<E> data : datas.values()) {
			for (E d : data) {
				count = counts.get(d);
				if (count == null) {
					counts.put(d, 1);
				} else {
					counts.put(d, count + 1);
				}
			}
		}
		// 规则排序：先抽少的，再抽多的，从而减少判断
		List<Entry<R, Integer>> ruleList = new ArrayList<>(rules.size());
		ruleList.addAll(rules.entrySet());
		ruleList.sort(Entry.comparingByValue());
		// 规则数据乱序
		for (List<E> data : datas.values()) {
			Collections.shuffle(data);
		}
		// 依次抽取
		Map<R, List<E>> result = new HashMap<>();
		Entry<R, Integer> rule;
		List<E> currDatas;
		E data;
		Entry<R, Integer> otherRule;
		List<E> otherDatas;
		List<List<E>> removeDatas = null;
		boolean isLast;
		boolean isRepeat = false;
		for (int i = 0; i < ruleList.size(); i++) {
			// 规则
			rule = ruleList.get(i);
			currDatas = new ArrayList<>();
			result.put(rule.getKey(), currDatas);
			isLast = i == ruleList.size() - 1;
			data: for (int j = 0; j < rule.getValue(); j++) {
				// 抽取数据
				data = datas.get(rule.getKey()).get(j);
				// 最后一个规则直接抽取，非最后一个规则判断冲突
				if (!isLast) {
					// 唯一数据直接抽取，非唯一数据判断冲突
					isRepeat = counts.get(data) > 1;
					if (isRepeat) {
						// 判断其它规则去掉重复数据后是否足够（投票决定本轮规则是否可用该数据）
						// 问题：可能后续轮次交叉冲突，导致投票翻盘，如果每层级规则都递归探测一圈，性能将大打折扣，所以不作处理，可以设置数据宽裕些，或者重试
						removeDatas = new ArrayList<>();
						for (int i2 = i + 1; i2 < ruleList.size(); i2++) {
							// 规则
							otherRule = ruleList.get(i2);
							// 规则数据
							otherDatas = datas.get(otherRule.getKey());
							// 是否重复
							if (otherDatas.contains(data)) {
								// 待清除的列表
								removeDatas.add(otherDatas);
								// 之前重复的数据在添加后会被清除，所以减去本轮数据即可
								if (otherDatas.size() - 1 < otherRule.getValue()) {
									// 某规则在去掉重复数据后不足，本规则不能抽取该数据
									continue data;
								}
							}
						}
					}
				}
				// 抽取
				currDatas.add(data);
				// 去重
				if (isRepeat) {
					for (List<E> list : removeDatas) {
						list.remove(data);
					}
					counts.remove(data);
					isRepeat = false;
				}
				// 抽取完成
				if (rule.getValue() == currDatas.size()) {
					break;
				}
			}
			// 抽取不足
			if (rule.getValue() > currDatas.size()) {
				return null;
			}
		}
		return result;
	}

	/**
	 * 选取数据（贪心算法）
	 * 
	 * 说明：从数据中整合所有可选项为待选项，然后选取多个宿主，使其可选项覆盖所有待选项
	 * 
	 * @param datas
	 *            数据：{宿主:可选项}
	 * 
	 * @return 选取失败 null；选择成功 {宿主:被选项}
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年7月28日
	 */
	public static <K, V> Map<K, Set<V>> greedySelect(Map<K, Set<V>> datas) {
		// 获取所有待选项
		Set<V> options = new HashSet<>();
		for (Set<V> v : datas.values()) {
			options.addAll(v);
		}
		// 选取
		return greedySelect(options, datas);
	}

	/**
	 * 选取数据（贪心算法）
	 * 
	 * 说明：从数据中，选取多个宿主，使其可选项覆盖所有待选项
	 * 
	 * @param options
	 *            待选项
	 * @param datas
	 *            数据：{宿主:可选项}
	 * 
	 * @return 选取失败 null；选择成功 {宿主:被选项}
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年7月28日
	 */
	public static <K, V> Map<K, Set<V>> greedySelect(Set<V> options, Map<K, Set<V>> datas) {
		// 获取局部最优解
		Map<K, Set<V>> selects = new LinkedHashMap<>();
		K select = null;
		Set<V> option;
		Set<V> selectOption = null;
		while (!options.isEmpty()) {
			// 局部求解
			for (Entry<K, Set<V>> data : datas.entrySet()) {
				// 可选项
				option = new HashSet<>(data.getValue());
				// 有效选项（交集）
				option.retainAll(options);
				// 选取最优解：有效选项 > 当前选择
				if (!option.isEmpty() && (select == null || option.size() > selectOption.size())) {
					select = data.getKey();
					selectOption = option;
				}
			}
			// 局部最优解
			if (select != null) {
				// 汇总局部最优解 > 整体求解
				selects.put(select, selectOption);
				// 清除已选项
				options.removeAll(datas.remove(select));
				select = null;
			}
		}
		// 整体结果
		return selects;
	}

	/**
	 * 所有元素不匹配
	 *
	 * @param list
	 * @param predicate
	 * @param <E>
	 * @return
	 */
	public static <E>boolean none(Collection<E> list, Predicate<? super E> predicate){
		return list.stream().noneMatch(predicate);
	}

	/**
	 * 任意元素匹配
	 *
	 * @param list
	 * @param predicate
	 * @param <E>
	 * @return
	 */
	public static <E>boolean some(Collection<E> list, Predicate<? super E> predicate){
		return list.stream().anyMatch(predicate);
	}

	/**
	 * 所有元素匹配
	 *
	 * @param list
	 * @param predicate
	 * @param <E>
	 * @return
	 */
	public static <E>boolean every(Collection<E> list, Predicate<? super E> predicate){
		return list.stream().allMatch(predicate);
	}

	/**
	 * 过滤列表
	 *
	 * @param list
	 * @param predicate
	 * @param <E>
	 * @return
	 *
	 * @author 延晓磊
	 * @since 2021年12月21日
	 */
	public static <E>List<E> filter(List<E> list, Predicate<? super E> predicate){
		return list.stream().filter(predicate).collect(Collectors.toList());
	}

	/**
	 * 过滤列表
	 *
	 * @param list
	 * @param predicate
	 * @param <E>
	 * @return
	 *
	 * @author 延晓磊
	 * @since 2021年12月21日
	 */
	public static <E>Set<E> filter(Set<E> list, Predicate<? super E> predicate){
		return list.stream().filter(predicate).collect(Collectors.toSet());
	}

	/**
	 * 过滤列表
	 *
	 * @param list
	 * @param filter	过滤名：‘’无，*全部，xx*模糊匹配，多个用,分隔
	 * @return
	 *
	 * @author 延晓磊
	 * @since 2020年10月10日
	 */
	public static List<String> filter(List<String> list, String filter){
		return filter(list, filter, null);
	}

	/**
	 * 过滤列表
	 *
	 * @param list
	 * @param filter	过滤名：‘’无，*全部，xx*模糊匹配，多个用,分隔
	 * @param noContainsHandler	指定名称不存在时的处理
	 * @return
	 *
	 * @author 延晓磊
	 * @since 2020年10月10日
	 */
	public static List<String> filter(List<String> list, String filter, Consumer<String> noContainsHandler){
		// 筛选
		if (CollectionUtils.isEmpty(list)) {
			return list;
		}
		filter = StringUtil.remove(filter);
		if (StringUtils.isBlank(filter)) {
			return new ArrayList<>();
		}
		if ("*".equals(filter)) {
			return list;
		} else if (filter.endsWith("*")) {
			// *后缀匹配
			List<String> ts = new ArrayList<>();
			for (String t : list) {
				if (AntUtil.ant(t, filter)) {
					ts.add(t);
				}
			}
			return ts;
		} else {
			// 单表 或 ,号分隔的多表
			List<String> ts = new ArrayList<>();
			String[] split = StringUtil.splitStrict(filter);
			for (String t : split) {
				if (StringUtils.isNotBlank(t)) {
					if (list.contains(t)) {
						ts.add(t);
					}else{
						if (noContainsHandler != null) {
							noContainsHandler.accept(t);
						}
					}
				}
			}
			return ts;
		}
	}

	/**
	 * 分组
	 *
	 * @param list
	 * @param key	获取KEY
	 * @param <T>
	 * @param <K>
	 * @return
	 *
	 * @author 延晓磊
	 * @since 2022年02月07日
	 */
	public static <T,K>Map<K,List<T>> group(List<T> list, Function<T,K> key){
		Map<K,List<T>> map = new HashMap<>();
		for (T t : list) {
			map.computeIfAbsent(key.apply(t), k -> new ArrayList<>()).add(t);
		}
		return map;
	}

	/**
	 * 分组
	 *
	 * @param list
	 * @param key	获取KEY
	 * @param <T>
	 * @param <K>
	 * @return
	 *
	 * @author 延晓磊
	 * @since 2022年02月07日
	 */
	public static <T,K>Map<K,Set<T>> group(Set<T> list, Function<T,K> key){
		Map<K,Set<T>> map = new HashMap<>();
		for (T t : list) {
			map.computeIfAbsent(key.apply(t), k -> new HashSet<>()).add(t);
		}
		return map;
	}

	/**
	 * 分组计数
	 *
	 * @param list
	 * @param key	获取KEY
	 * @param <T>
	 * @param <K>
	 * @return
	 *
	 * @author 延晓磊
	 * @since 2022年02月07日
	 */
	public static <T,K>Map<K,Integer> groupCount(List<T> list, Function<T,K> key){
		Map<K,Integer> map = new HashMap<>();
		K k;
		for (T t : list) {
		    k = key.apply(t);
		    map.put(k, IntegerUtil.toEmpty(map.get(k)) + 1);
		}
		return map;
	}

	/**
	 * 分组求和
	 *
	 * @param list
	 * @param key	获取KEY
	 * @param val	获取VAL
	 * @param <T>
	 * @param <K>
	 * @return
	 *
	 * @author 延晓磊
	 * @since 2022年02月07日
	 */
	public static <T,K>Map<K, BigDecimal> groupSum(List<T> list, Function<T,K> key, Function<T,BigDecimal> val){
		Map<K,BigDecimal> map = new HashMap<>();
		K k;
		for (T t : list) {
			k = key.apply(t);
			map.put(k, DecimalUtil.toEmpty(map.get(k)).add(val.apply(t)));
		}
		return map;
	}

	/**
	 * 空转null
	 * 
	 * @param list
	 * @param <T>
	 * @return
	 * 
	 * @author 延晓磊
	 * @since 2021年09月30日
	 */
	public static <T>List<T> toNull(List<T> list){
		return CollectionUtils.isEmpty(list) ? null : list;
	}

	/**
	 * 空转[]
	 *
	 * @param list
	 * @param <T>
	 * @return
	 *
	 * @author 延晓磊
	 * @since 2021年09月30日
	 */
	public static <T>List<T> toEmpty(List<T> list){
		return list == null ? new ArrayList<>() : list;
	}

	/**
	 * 空转null
	 *
	 * @param list
	 * @param <T>
	 * @return
	 *
	 * @author 延晓磊
	 * @since 2021年09月30日
	 */
	public static <T>Set<T> toNull(Set<T> list){
		return CollectionUtils.isEmpty(list) ? null : list;
	}

	/**
	 * 空转[]
	 *
	 * @param list
	 * @param <T>
	 * @return
	 *
	 * @author 延晓磊
	 * @since 2021年09月30日
	 */
	public static <T>Set<T> toEmpty(Set<T> list){
		return list == null ? new HashSet<>() : list;
	}

	/**
	 * 空转null
	 *
	 * @param list
	 * @param <T>
	 * @return
	 *
	 * @author 延晓磊
	 * @since 2021年09月30日
	 */
	public static <T>Collection<T> toNull(Collection<T> list){
		return CollectionUtils.isEmpty(list) ? null : list;
	}

	/**
	 * 空转[]
	 *
	 * @param list
	 * @param <T>
	 * @return
	 *
	 * @author 延晓磊
	 * @since 2021年09月30日
	 */
	public static <T>Collection<T> toEmpty(Collection<T> list){
		return list == null ? new ArrayList<>() : list;
	}

	/**
	 * 如果o非空，执行fn(o)
	 *
	 * @param o		对象
	 * @param fn	如果o非empty执行fn.accept(o)
	 * @return
	 *
	 * @author 延晓磊
	 *
	 * @since 2020年3月18日
	 */
	public static <T>void consumer(Collection<T> o, Consumer<Collection<T>> fn){
		if (CollectionUtils.isNotEmpty(o)) {
			fn.accept(o);
		}
	}

	/**
	 * 如果o为空，nullFn；如果非空，执行notNullFn
	 *
	 * @param o		对象
	 * @param nullFn	为空时执行
	 * @param notNullFn	非空时执行
	 * @return
	 *
	 * @author 延晓磊
	 *
	 * @since 2020年3月18日
	 */
	public static <T>void consumer(Collection<T> o, Consumer<Collection<T>> nullFn, Consumer<Collection<T>> notNullFn){
		if (CollectionUtils.isEmpty(o)) {
			nullFn.accept(o);
		}else{
			notNullFn.accept(o);
		}
	}

	/**
	 * 生成列表
	 *
	 * @param start	起始值
	 * @param size	数量
	 * @return
	 *
	 * @author 延晓磊
	 * @since 2023年08月18日
	 */
	public static List<Integer> gen(int start, int size){
		List<Integer> list = new ArrayList<>(size);
		for (int i = start; i < start + size; i++) {
			list.add(i);
		}
		return list;
	}
}
